//---------------------------------------------------------------------
//  This file is part of the Background Motion solution.
// 
//  Copyright (C) Mindscape (TM).  All rights reserved.
//  http://www.mindscape.co.nz
// 
//  THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//  PARTICULAR PURPOSE.
//---------------------------------------------------------------------

using Mindscape.BackgroundMotion.Model;
using Mindscape.BackgroundMotion.Website.Controllers;
using Mindscape.BackgroundMotion.Website.Infrastructure;
using System;

namespace Mindscape.BackgroundMotion.Website.Views
{
  public sealed class ViewPresenter : PresenterBase<IViewView, IContributionController>
  {
    /// <summary>
    /// Adds a rating to the current <see ref="Contribution"/> loaded with the view
    /// </summary>
    /// <param name="rating">The rating.</param>
    public void AddRating(Contribution.RatingValue rating)
    {
      View.Contribution.AddRating(rating);
      Controller.UpdateContribution(View.Contribution);
    }

    /// <summary>
    /// Approves the contribution.
    /// </summary>
    /// <param name="contribution">The contribution to approve.</param>
    public void ApproveContribution(Contribution contribution)
    {
      Controller.ApproveContribution(contribution.Id);
    }
    
    /// <summary>
    /// Deletes the contribution.
    /// </summary>
    /// <param name="contribution">The contribution to delete.</param>
    public void DeleteContribution(Contribution contribution)
    {
      Controller.DeleteContribution(contribution.Id);
    }

    /// <summary>
    /// Adds a rating to the download experience of the current <see ref="Contribution"/> loaded with the view
    /// </summary>
    /// <param name="rating">The rating.</param>
    public void AddDownloadExperienceRating(Contribution.RatingValue rating)
    {
      View.Contribution.AddDownloadExperienceRating(rating);
      Controller.UpdateContribution(View.Contribution);
    }

    /// <summary>
    /// Adds a new <see ref="Comment"/> to the current <see ref="Contribution"/> loaded with the view
    /// </summary>
    /// <param name="subject">The subject of the commment.</param>
    /// <param name="message">The message of the comment.</param>
    public void AddComment(string subject, string message)
    {
      Comment comment = new Comment();
      comment.Subject = subject;
      comment.Message = message;
      View.Contribution.Comments.Add(comment);
      comment.Member = Controller.CurrentMember;

      if (!comment.ValidationResults.IsValid)
      {
        View.ValidationResults = comment.ValidationResults;
        View.Contribution.Comments.Remove(comment);
      }
      else
      {
        Controller.UpdateContribution(View.Contribution);
        View.ValidationResults = null;
        View.ClearLastComment();
      }

      OnViewLoaded();
    }

    /// <summary>
    /// This method is invoked by the view everytime it loads
    /// </summary>
    public override void OnViewLoaded()
    {
      View.CanAddComments = Controller.IsLoggedIn;
      View.CanRate = Controller.IsLoggedIn;      

      int? id = Controller.GetParameter<int?>("id");

      if (id != null)
      {
        Contribution contribution;

        if (null != (contribution = Controller.ViewContribution(id.Value)))
        {
          View.Preview = ParsePreviewLink(contribution);
          View.Contribution = contribution;

          if (Controller.IsLoggedIn)
          {
            View.CanDelete = (Controller.CurrentMember.IsModerator ||
                              Controller.CurrentMember == contribution.Contributor);

            View.CanApprove = (Controller.CurrentMember.IsModerator & !contribution.ApprovedById.HasValue);
          }
        }
        else
        {
          Controller.RedirectTo("~");
        }
      }
    }

    /// <summary>
    /// Parses the preview link from a contribution
    /// </summary>
    /// <param name="contribution">The contribution to parse from.</param>
    /// <returns>The parsed preview link</returns>
    private string ParsePreviewLink(Contribution contribution)
    {
      if (contribution.PreviewLink != null)
      {
        Uri uri = new Uri(contribution.PreviewLink);

        switch(uri.Host)
        {
          case "www.youtube.com":
            return ParseYouTube(uri);
          case "silverlight.services.live.com":
            return ParseSilverlightStreaming(uri);
          default:
            if (contribution.DownloadLink.EndsWith(".wmv") && contribution.PreviewLink.EndsWith(".wmv"))
            {
              return ParseInlineSilverlight(contribution);
            }
            else
            {
              return
                string.Format("<div class=\"contentShadow\"><img src=\"{0}\" alt=\"{1}\"/></div>",
                              contribution.PreviewImage, contribution.Description);
            }
        }
      }

      // No preview link, use the small preview image
      return contribution.PreviewImage;
    }

    private string ParseInlineSilverlight(Contribution contribution)
    {
      View.EnableSilverlightScriptRendering(false);
      return string.Concat("<br/><div id=\"SilverlightWrapper\"></div><script type=\"text/javascript\">createPlayer('SilverlightWrapper','" + contribution.PreviewLink + "','" + contribution.PreviewImage + "', '');</script>");
    }

    private string ParseSilverlightStreaming(Uri link)
    {
      View.EnableSilverlightScriptRendering(true);
      return string.Concat("<br/><div id=\"SilverlightWrapper\" style=\"width:425px; height:350px; overflow:hidden;\"></div><script type=\"text/javascript\">var SilverlightWrapper = document.getElementById(\"SilverlightWrapper\");Sys.Silverlight.createHostedObjectEx({source: \"streaming:", link.PathAndQuery, "\",parentElement: SilverlightWrapper});</script>");
    }

    /// <summary>
    /// Parses a YouTube link and returns an object embed tag
    /// </summary>
    /// <param name="link">The link.</param>
    /// <returns>Either the link if this is not a YouTube resource, else an embed tag which contains the code needed to display an inline YouTube video instance</returns>
    private string ParseYouTube(Uri link)
    {
     string result;

      int startIndex = link.Query.IndexOf("v=");
      if (startIndex == -1)
      {
        return link.ToString();
      }

      int endIndex = link.Query.IndexOf("&");//, startIndex);
      if (endIndex == -1)
      {
        endIndex = link.Query.Length;
      }

      result = link.Query.Substring(startIndex + 2, endIndex - 3);

      return string.Format("<object width=\"425\" height=\"350\"><param name=\"movie\" value=\"http://www.youtube.com/v/{0}\"></param><param name=\"wmode\" value=\"transparent\"></param><embed src=\"http://www.youtube.com/v/{0}\" type=\"application/x-shockwave-flash\" wmode=\"transparent\" width=\"425\" height=\"350\"></embed></object>", result);
    }
  }
}